/*
 * @Author: wuqingchun
 * @Date: 2024-04-15 16:06:16
 * @Description: C++ 函数相关语法
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-04-15 19:47:33
 */

#include <iostream>
#include <functional>

#include "std_bind.h"

void ShowValue(int iValue)
{
    std::cout << iValue << std::endl;
}

// 可以这么理解定义：因为(*g_pfCB)表示函数，那么 g_pfCB 就是函数的指针
void (*g_pfCB)(int) = ShowValue;

// 函数指针的定义一般都不怎么直接，使用也不方面
// 经典C++中可以使用 typedef 简化这个定义
typedef void (*CALL_BACK_PF)(int); // 现在 CALL_BACK_PF 是一种类型

CALL_BACK_PF g_pfCB2 = ShowValue;

// 现代C++提供了 using 语法让这个过程更加直观，推荐使用
using PF_CALLBACK = void(*)(int);
PF_CALLBACK g_pfCB3 = ShowValue;

// 函数指针实现回调机制
void processTrans(int iValue, CALL_BACK_PF pfCB)
{
    // 函数名使用方式
    pfCB(iValue);
    // 指针使用方式
    (*pfCB)(iValue);

    g_pfCB(iValue);
    (*g_pfCB)(iValue);

    g_pfCB2(iValue);
    (*g_pfCB2)(iValue);

    g_pfCB3(iValue);
    (*g_pfCB3)(iValue);
}


using CALLABLE_ENTITY = std::function<void(int)>;

// 函数对象
class CallableEntity
{
public:
    void operator()(int iValue)
    {
        std::cout << iValue << std::endl;
    }
};

class Tools
{
public:
    void ShowValue(int iValue)
    {
        std::cout << iValue << std::endl;
    }

    static void SShowValue(int iValue)
    {
        std::cout << iValue << std::endl;
    }
};

int main(int argc, char** argv)
{
    // 函数指针实现回调机制
    processTrans(10, ShowValue);

    // 封装普通函数
    std::function<void(int)> objFuntion = ShowValue;
    objFuntion(100);

    // 封装 lambda 表达式
    objFuntion = [](int iValue){std::cout << iValue << std::endl;};
    objFuntion(101);

    // 封装函数对象
    objFuntion = CallableEntity();
    objFuntion(102);

    // 封装类的成员函数
    Tools objTools;
    objFuntion = std::bind(&Tools::ShowValue, &objTools, std::placeholders::_1);
    objFuntion(103);

    // 封装类的静态成员函数
    objFuntion = Tools::SShowValue;
    objFuntion(104);

    TestSTDBind objStdBind;
    objStdBind.BindNormalFunction();
    objStdBind.BindClassMemberFunction();
    objStdBind.BindLambda();

    return 0;
}